#include "sqlwlisttablemodel.h"
#include "../MainStation/mainwindow.h"
#include "../share/global.h"

#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QVariant>
#include <QSqlRecord>
#include <QDir>

SqlWlistTableModel::SqlWlistTableModel(QObject *parent) :
    QSqlTableModel(parent, QSqlDatabase::database(WLIST_DB_CONNECTION_NAME))
{
    init();
}

void SqlWlistTableModel::init()
{
    setTable("WlistTable");
    setSort(ModifyTime, Qt::DescendingOrder);
    setEditStrategy(QSqlTableModel::OnFieldChange);
}

bool SqlWlistTableModel::initWlistDb(QString &result, bool recreate)
{
    QString dbPath = mainWindow->getDbConfig().imagePath;
    if (!QDir().mkpath(dbPath)) {
        result = tr("Cannot create database path, check settings.");
        return false;
    }

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", WLIST_DB_CONNECTION_NAME);
    db.setDatabaseName(QString("%1/%2").arg(dbPath, WLIST_DB_NAME));
    if (db.open()) {
        if (recreate) {
            db.exec("DROP INDEX IX_WlistTable_ModifyTime ON WlistTable");
            db.exec("DROP TABLE WlistTable");
        }
        db.exec("CREATE TABLE IF NOT EXISTS WlistTable(StudyUid VARCHAR(128) PRIMARY KEY NOT NULL,"
                "AccNumber VARCHAR(64) NOT NULL, PatientId VARCHAR(64) NOT NULL,"
                "PatientName VARCHAR(64), PatientSex VARCHAR(2) NOT NULL,"
                "PatientBirth DATE NOT NULL, PatientAge VARCHAR(6),"
                "ReqPhysician VARCHAR(64), ReqProcPrio VARCHAR(6),"
                "ReqProcId VARCHAR(128), ReqProcDesc TEXT,"
                "Modality VARCHAR(2), SchDateTime DATETIME, SchPhysician VARCHAR(64),"
                "SchStationAe VARCHAR(64), SchStationName VARCHAR(128),"
                "SchProcStepId VARCHAR(64),"
                "SchProcStepDesc TEXT, AdmissionId VARCHAR(64),"
                "Department VARCHAR(128), PatientSize VHARCHAR(9),"
                "PatientWeight VARCHAR(9), PatientPhone VARCHAR(18),"
                "PatientAddr TEXT, MedicalAlerts TEXT,"
                "CreateTime DATETIME, ModifyTime DATETIME)");
        db.exec("CREATE INDEX IF NOT EXISTS IX_WlistTable_SchDateTime ON WlistTable(SchDateTime)");
    }

    result = db.lastError().text();
    return db.lastError().type() == QSqlError::NoError;
}

QVariant SqlWlistTableModel::data(const QModelIndex &idx, int role) const
{
    if (Qt::DisplayRole == role && idx.isValid()) {
        QSqlRecord rec = record(idx.row());
        switch (idx.column()) {
        case PatientSex:
            return sex2trSex(rec.value(PatientSex).toString());
        case ReqProcPrio: {
            QString value = rec.value(ReqProcPrio).toString();
            if (value == "LOW") return tr("LOW");
            else if (value == "MEDIUM") return tr("MEDIUM");
            else return tr("HIGH");
        }
        case PatientBirth:
            return QDate::fromString(rec.value(PatientBirth).toString(), DATE_DICOM_FORMAT);
        case SchDateTime:
            return QDateTime::fromString(rec.value(SchDateTime).toString(), DATETIME_DICOM_FORMAT);
        default:
            return QSqlTableModel::data(idx, role);
        }
    } else return QSqlTableModel::data(idx, role);
}

QVariant SqlWlistTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (Qt::Horizontal == orientation) {
        if (Qt::DisplayRole == role) {
            switch (section) {
            case AccNumber:
                return QVariant(tr("Acc Number"));
            case PatientId:
                return QVariant(tr("Patient ID"));
            case PatientName:
                return QVariant(tr("Patient Name"));
            case PatientSex:
                return QVariant(tr("Sex"));
            case PatientBirth:
                return QVariant(tr("Birth Date"));
            case PatientAge:
                return tr("Age");

            case ReqPhysician:
                return QVariant(tr("Req Physician"));
            case ReqProcId:
                return QVariant(tr("Req Proc ID"));
            case ReqProcPrio:
                return QVariant(tr("Req Priority"));
            case ReqProcDesc:
                return QVariant(tr("Req Proc Desc"));

            case Modality:
                return QVariant(tr("Modality"));
            case SchStationAe:
                return QVariant(tr("Sch Station AE"));
            case SchStationName:
                return QVariant(tr("Sch Station Name"));
            case SchPhysician:
                return QVariant(tr("Sch Physician"));
            case SchDateTime:
                return QVariant(tr("Sch DateTime"));
            case SchProcStepId:
                return QVariant(tr("Sch Proc Step ID"));
            case SchProcStepDesc:
                return QVariant(tr("Sch Proc Step Desc"));

            case AdmissionId:
                return QVariant(tr("Admission ID"));
            case Department:
                return QVariant(tr("Department"));
            case PatientSize:
                return QVariant(tr("Size(cm)"));
            case PatientWeight:
                return QVariant(tr("Weight(Kg)"));
            case PatientPhone:
                return QVariant(tr("Phone Number"));
            case PatientAddr:
                return QVariant(tr("Address"));
            case MedicalAlerts:
                return tr("Medical Alerts");
            case CreateTime:
                return QVariant(tr("Create Time"));
            case ModifyTime:
                return QVariant(tr("Modify Time"));

            default:
                return QVariant();
            }
        }
        return QVariant();
    } else {
        if (Qt::DisplayRole == role) {
            return QVariant(section+1);
        } else return QVariant();
    }
}

void SqlWlistTableModel::onNewPatient(const QModelIndex &index)
{
    emit newPatient(record());
}

void SqlWlistTableModel::onNewStudy(const QModelIndex &index)
{
    emit newStudy(record(index.row()));
}

void SqlWlistTableModel::onChangeStudy(const QModelIndex &index)
{
    currentRow = index.row();
    emit changeStudy(record(index.row()));
}

void SqlWlistTableModel::onRemoveStudy(const QModelIndex &index)
{
    currentRow = index.row();
    emit removeStudy(record(index.row()));
}

void SqlWlistTableModel::onNewPatient(QSqlRecord &rec)
{
    insertRecord(0, rec);
}

void SqlWlistTableModel::onNewStudy(QSqlRecord &rec)
{
    insertRecord(0, rec);
}

void SqlWlistTableModel::onChangeStudy(QSqlRecord &rec)
{
    setRecord(currentRow, rec);
}

void SqlWlistTableModel::onRemoveStudy()
{
    removeRow(currentRow);
    select();
}
